package com.example.lexiangbackend.service;

import com.example.lexiangbackend.dto.MusicUploadRequest;
import com.example.lexiangbackend.entity.Music;
import com.example.lexiangbackend.entity.MusicCategory;
import com.example.lexiangbackend.repository.MusicRepository;
import com.example.lexiangbackend.repository.MusicCategoryRepository;
import com.example.lexiangbackend.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class MusicService {

    @Autowired
    private MusicRepository musicRepository;

    @Autowired
    private MusicCategoryRepository categoryRepository;

    @Autowired
    private FileUtil fileUtil;

    @Autowired
    private UrlMusicService urlMusicService;

    @Value("${file.upload.path:lexiangbackend/src/main/uploads}")
    private String fileUploadPath;

    /**
     * 上传音乐
     */
    public Music uploadMusic(MusicUploadRequest request) {
        try {
            // 验证分类是否存在
            Optional<MusicCategory> categoryOpt = categoryRepository.findById(request.getCategoryId());
            if (categoryOpt.isEmpty()) {
                throw new RuntimeException("分类不存在");
            }

            String finalMusicUrl;
            String finalCoverUrl = request.getCoverUrl();
            int finalDuration = request.getDuration() != null ? request.getDuration() : 0;

            // 根据上传类型处理音乐URL
            if ("URL".equals(request.getUploadType())) {
                // URL上传方式
                if (request.getExternalUrl() == null || request.getExternalUrl().isEmpty()) {
                    throw new RuntimeException("外部音乐URL不能为空");
                }

                // 验证并处理外部URL
                finalMusicUrl = urlMusicService.processExternalUrl(request.getExternalUrl());
                
                // 尝试获取音乐元数据
                try {
                    UrlMusicService.MusicMetadata metadata = urlMusicService.getMusicMetadata(request.getExternalUrl());
                    if (metadata.getDuration() > 0) {
                        finalDuration = metadata.getDuration();
                    }
                } catch (Exception e) {
                    System.err.println("获取音乐元数据失败，使用用户提供的信息: " + e.getMessage());
                }
                
                System.out.println("使用URL上传: " + finalMusicUrl);
                
            } else {
                // 文件上传方式（原有逻辑）
                if (!validateFileExists(request.getMusicUrl())) {
                    throw new RuntimeException("音乐文件不存在或上传失败");
                }
                finalMusicUrl = request.getMusicUrl();
                
                if (request.getCoverUrl() != null && !request.getCoverUrl().isEmpty() && !validateFileExists(request.getCoverUrl())) {
                    throw new RuntimeException("封面图片不存在或上传失败");
                }
            }

            Music music = new Music();
            // 设置数据库必需的字段
            music.setName(request.getTitle()); // name字段映射到title
            music.setSinger(request.getArtist()); // singer字段映射到artist
            music.setTitle(request.getTitle());
            music.setArtist(request.getArtist());
            music.setDuration(finalDuration);
            music.setFilePath(finalMusicUrl);
            music.setCoverPath(finalCoverUrl);
            music.setUploadTime(LocalDateTime.now());
            
            // 设置分类关系
            music.setCategory(categoryOpt.get());
            
            // 设置播放次数（如果提供了，否则默认为0）
            music.setPlayCount(request.getPlayCount() != null ? request.getPlayCount() : 0L);
            
            // 保存音乐信息（包括分类关系）
            Music savedMusic = musicRepository.save(music);
            
            System.out.println("音乐上传成功: " + savedMusic.getName() + " - " + savedMusic.getFilePath());
            
            return savedMusic;
        } catch (Exception e) {
            throw new RuntimeException("音乐上传失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 验证文件是否存在
     */
    private boolean validateFileExists(String fileUrl) {
        try {
            if (fileUrl == null || fileUrl.isEmpty()) {
                return false;
            }
            
            String fileName = fileUtil.extractFileNameFromUrl(fileUrl);
            if (fileName == null) {
                return false;
            }
            
            String fileType = fileUtil.getFileTypeDirectory(fileName);
            if (fileType == null) {
                return false;
            }
            
            String fullPath = fileUploadPath + "/" + fileType + "/" + fileName;
            Path path = Paths.get(fullPath);
            return Files.exists(path) && Files.isReadable(path);
        } catch (Exception e) {
            System.err.println("验证文件存在时出错: " + e.getMessage());
            return false;
        }
    }

    /**
     * 获取所有音乐（分页）
     */
    public Page<Music> getAllMusic(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return musicRepository.findAll(pageable);
    }

    /**
     * 更新音乐信息
     */
    public Music updateMusic(Long musicId, MusicUploadRequest request) {
        Optional<Music> musicOpt = musicRepository.findById(musicId);
        if (musicOpt.isEmpty()) {
            throw new RuntimeException("音乐不存在");
        }

        // 验证分类是否存在
        Optional<MusicCategory> categoryOpt = categoryRepository.findById(request.getCategoryId());
        if (categoryOpt.isEmpty()) {
            throw new RuntimeException("分类不存在");
        }

        Music music = musicOpt.get();
        
        // 记录旧的文件路径
        String oldMusicPath = music.getFilePath();
        String oldCoverPath = music.getCoverPath();
        
        // 更新音乐信息
        music.setName(request.getTitle()); // name字段映射到title
        music.setSinger(request.getArtist()); // singer字段映射到artist
        music.setTitle(request.getTitle());
        music.setArtist(request.getArtist());
        music.setDuration(request.getDuration() != null ? request.getDuration() : 0);
        music.setFilePath(request.getMusicUrl());
        music.setCoverPath(request.getCoverUrl());
        
        // 更新分类关系
        music.setCategory(categoryOpt.get());
        
        // 更新播放次数（如果提供了的话）
        if (request.getPlayCount() != null) {
            music.setPlayCount(request.getPlayCount());
        }

        // 保存更新后的音乐信息
        Music savedMusic = musicRepository.save(music);
        
        // 删除旧文件（如果文件路径发生了变化）
        try {
            if (oldMusicPath != null && !oldMusicPath.equals(request.getMusicUrl())) {
                fileUtil.deleteFileFromUrl(oldMusicPath, "songs");
            }
            if (oldCoverPath != null && !oldCoverPath.equals(request.getCoverUrl())) {
                fileUtil.deleteFileFromUrl(oldCoverPath, "covers");
            }
        } catch (Exception e) {
            System.err.println("删除旧文件时出错: " + e.getMessage());
            // 即使删除旧文件失败，也返回更新后的音乐信息
        }

        return savedMusic;
    }

    /**
     * 删除音乐
     */
    public void deleteMusic(Long musicId) {
        // 先查询音乐信息，获取文件路径
        Optional<Music> musicOpt = musicRepository.findById(musicId);
        if (musicOpt.isEmpty()) {
            throw new RuntimeException("音乐不存在");
        }
        
        Music music = musicOpt.get();
        
        // 删除相关文件
        deleteAssociatedFiles(music);
        
        // 删除数据库记录
        musicRepository.deleteById(musicId);
    }
    
    /**
     * 删除音乐相关的文件
     */
    private void deleteAssociatedFiles(Music music) {
        try {
            // 使用FileUtil统一删除文件
            fileUtil.deleteMusicFiles(music.getFilePath(), music.getCoverPath());
        } catch (Exception e) {
            System.err.println("删除文件时出错: " + e.getMessage());
            // 即使文件删除失败，也继续删除数据库记录
        }
    }
    

    


    /**
     * 根据ID获取音乐
     */
    public Music getMusicById(Long musicId) {
        return musicRepository.findById(musicId)
                .orElseThrow(() -> new RuntimeException("音乐不存在"));
    }

    /**
     * 获取音乐总数
     */
    public long getMusicCount() {
        return musicRepository.count();
    }

    /**
     * 根据分类获取音乐
     */
    public Page<Music> getMusicByCategory(Long categoryId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        if (categoryId == null) {
            return musicRepository.findAll(pageable);
        }
        // 使用Repository中的按分类查询方法
        return musicRepository.findByCategoryId(categoryId, pageable);
    }

    /**
     * 搜索音乐
     */
    public List<Music> searchMusic(String keyword) {
        // 暂时返回所有音乐，后续可添加到Repository中
        return musicRepository.findAll();
    }
    
    /**
     * 获取热门音乐（按播放量排序）
     */
    public Page<Music> getHotMusic(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return musicRepository.findAllByOrderByPlayCountDesc(pageable);
    }
    
    /**
     * 获取推荐音乐（混合热门和最新音乐）
     */
    public List<Music> getRecommendedMusic(int limit) {
        List<Music> recommendedMusic = new ArrayList<>();
        
        try {
            // 获取热门音乐（播放量高的）
            int hotMusicCount = Math.min(limit / 2, 10);
            Pageable hotPageable = PageRequest.of(0, hotMusicCount);
            Page<Music> hotMusic = musicRepository.findAllByOrderByPlayCountDesc(hotPageable);
            recommendedMusic.addAll(hotMusic.getContent());
            
            // 获取最新上传的音乐
            int latestMusicCount = limit - recommendedMusic.size();
            if (latestMusicCount > 0) {
                Pageable latestPageable = PageRequest.of(0, latestMusicCount);
                Page<Music> latestMusic = musicRepository.findAllByOrderByUploadTimeDesc(latestPageable);
                
                // 避免重复添加已经在热门音乐中的歌曲
                for (Music music : latestMusic.getContent()) {
                    if (recommendedMusic.stream().noneMatch(m -> m.getMusicId().equals(music.getMusicId()))) {
                        recommendedMusic.add(music);
                        if (recommendedMusic.size() >= limit) {
                            break;
                        }
                    }
                }
            }
            
            // 如果还不够，随机添加一些音乐
            if (recommendedMusic.size() < limit) {
                int remainingCount = limit - recommendedMusic.size();
                Pageable randomPageable = PageRequest.of(0, remainingCount * 2); // 获取更多以便过滤
                Page<Music> randomMusic = musicRepository.findAllByOrderByMusicIdAsc(randomPageable);
                
                for (Music music : randomMusic.getContent()) {
                    if (recommendedMusic.stream().noneMatch(m -> m.getMusicId().equals(music.getMusicId()))) {
                        recommendedMusic.add(music);
                        if (recommendedMusic.size() >= limit) {
                            break;
                        }
                    }
                }
            }
            
        } catch (Exception e) {
            // 如果推荐算法失败，返回所有音乐的前N首
            Pageable fallbackPageable = PageRequest.of(0, limit);
            Page<Music> fallbackMusic = musicRepository.findAll(fallbackPageable);
            recommendedMusic = new ArrayList<>(fallbackMusic.getContent());
        }
        
        return recommendedMusic;
    }
    
    /**
     * 清理孤立文件（删除不被任何音乐记录引用的文件）
     */
    public void cleanOrphanFiles() {
        try {
            // 获取所有音乐记录中的文件路径
            List<Music> allMusic = musicRepository.findAll();
            
            // 收集所有在用的文件名
            List<String> usedFiles = allMusic.stream()
                .flatMap(music -> {
                    List<String> files = new ArrayList<>();
                    if (music.getFilePath() != null) {
                        String fileName = fileUtil.extractFileNameFromUrl(music.getFilePath());
                        if (fileName != null) files.add(fileName);
                    }
                    if (music.getCoverPath() != null) {
                        String fileName = fileUtil.extractFileNameFromUrl(music.getCoverPath());
                        if (fileName != null) files.add(fileName);
                    }
                    return files.stream();
                })
                .distinct()
                .toList();
            
            // 检查并删除孤立的音乐文件
            cleanOrphanFilesInDirectory(fileUploadPath + "/songs", usedFiles);
            
            // 检查并删除孤立的封面文件
            cleanOrphanFilesInDirectory(fileUploadPath + "/covers", usedFiles);
            
        } catch (Exception e) {
            System.err.println("清理孤立文件时出错: " + e.getMessage());
        }
    }
    
    /**
     * 清理指定目录中的孤立文件
     */
    private void cleanOrphanFilesInDirectory(String directoryPath, List<String> usedFiles) {
        try {
            Path dir = Paths.get(directoryPath);
            if (!Files.exists(dir)) {
                return;
            }
            
            Files.list(dir)
                .filter(Files::isRegularFile)
                .forEach(file -> {
                    String fileName = file.getFileName().toString();
                    if (!usedFiles.contains(fileName)) {
                        try {
                            Files.delete(file);
                            System.out.println("已删除孤立文件: " + file.toString());
                        } catch (Exception e) {
                            System.err.println("删除孤立文件失败: " + file.toString());
                        }
                    }
                });
        } catch (Exception e) {
            System.err.println("扫描目录失败: " + directoryPath);
        }
    }
} 